package com.my.createtype.prototype;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
/*
 * 	1.使用原型模式复制对象不会调用类的构造方法。因为对象的复制是通过调用Object类的clone方法来完成的，它直接在内存中复制数据，因此不会调用到类的构造方法。
 * 	不但构造方法中的代码不会执行，甚至连访问权限都对原型模式无效。还记得单例模式吗？单例模式中，只要将构造方法的访问权限设置为private型，就可以实现单例。
 * 	但是clone方法直接无视构造方法的权限，所以，单例模式与原型模式是冲突的，在使用时要特别注意。
	2.深拷贝与浅拷贝。Object类的clone方法只会拷贝对象中的基本的数据类型，对于数组、容器对象、引用对象等都不会拷贝，这就是浅拷贝。如果要实现深拷贝，
	必须将原型模式中的数组、容器对象、引用对象等另行拷贝
	3.ArrayList不是基本类型，所以成员变量list，不会被拷贝，需要我们自己实现深拷贝，幸运的是java提供的大部分的容器类都实现了Cloneable接口
	4.会发生深拷贝的有java中的8中基本类型以及他们的封装类型，另外还有String类型。其余的都是浅拷贝
 */
public class Prototype implements Cloneable {

	private String name;
	// 对于复杂属性,只是变量复制了一份,而真正的对象在内存中只有一份,所以需要深度复制
	private List<String> children;
	
	private HashSet<String> set;
	private String[] sons;

	/**
	 * @return the sons
	 */
	public String[] getSons() {
		return sons;
	}

	/**
	 * @param sons the sons to set
	 */
	public void setSons(String[] sons) {
		this.sons = sons;
	}

	/**
	 * @return the children
	 */
	public List<String> getChildren() {
		return children;
	}

	/**
	 * @param children the children to set
	 */
	public void setChildren(List<String> children) {
		this.children = children;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#clone()
	 */
	@Override
	public Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		Prototype proto = (Prototype) super.clone();
		
		proto.children = new ArrayList<String>(children);// 深度复制
		proto.set = (HashSet<String>) set.clone();
		
		return proto;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Prototype [name=" + name + ", children=" + children + ", sons="
				+ Arrays.toString(sons) + "]";
	}

	
	
}
